using FytSoa.Application.Analytical.CrmDto;
using FytSoa.Application.Analytical.ErpDto;
using FytSoa.Common.Enum;
using FytSoa.Domain.Erp;
using FytSoa.Sugar;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;

namespace FytSoa.Application.Analytical;
/// <summary>
/// ERP工作台
/// </summary>
[ApiExplorerSettings(GroupName = "v1")]
public class ErpAnalyticalService : IApplicationService
{
    private readonly int year = DateTime.Now.Year;
    
    private readonly SugarRepository<ErpProduct> _productRepository;
    private readonly SugarRepository<ErpPurchaseOrder> _cgoRepository;
    private readonly SugarRepository<ErpPurchaseApply> _cgaRepository;
    private readonly SugarRepository<ErpInstock> _instockRepository;
    private readonly SugarRepository<ErpOutstock> _outstockRepository;
    private readonly SugarRepository<ErpTakestockOrder> _takestockRepository;
    private readonly SugarRepository<ErpProduceOrder> _scoRepository;
    private readonly SugarRepository<ErpWarehouse> _warehouseRepository;
    public ErpAnalyticalService(SugarRepository<ErpProduct> productRepository
    ,SugarRepository<ErpPurchaseOrder> cgoRepository
    ,SugarRepository<ErpPurchaseApply> cgaRepository
    ,SugarRepository<ErpInstock> instockRepository
    ,SugarRepository<ErpOutstock> outstockRepository
    ,SugarRepository<ErpTakestockOrder> takestockRepository
    ,SugarRepository<ErpProduceOrder> scoRepository
    ,SugarRepository<ErpWarehouse> warehouseRepository)
    {
        _productRepository = productRepository;
        _cgoRepository = cgoRepository;
        _cgaRepository = cgaRepository;
        _instockRepository = instockRepository;
        _outstockRepository = outstockRepository;
        _takestockRepository = takestockRepository;
        _scoRepository = scoRepository;
        _warehouseRepository = warehouseRepository;
    }
    
    /// <summary>
    /// 总数据汇总
    /// </summary>
    /// <returns></returns>
    public async Task<ErpAnalyticalTotalDto> GetTotalAsync()
    {
        var res = new ErpAnalyticalTotalDto()
        {
            Product = await _productRepository.CountAsync(m=>m.ProductTag==ErpProductTagEnum.All),
            Material=await _productRepository.CountAsync(m=>m.ProductTag==ErpProductTagEnum.Materiel),
            ProductLoss=await _productRepository.CountAsync(m=>m.ProductTag==ErpProductTagEnum.Scrap),
            PruchaseOrder=await _cgoRepository.CountAsync(m=>true),
            PruchaseMoney= await _cgoRepository.AsQueryable().SumAsync(m=>m.Amount),
            ApplyMaterial = await _cgaRepository.CountAsync(m=>true),
            InStock=await _instockRepository.CountAsync(m=>true),
            OutStock= await _outstockRepository.CountAsync(m=>true),
            LossMoney= await _takestockRepository.AsQueryable().SumAsync(m=>m.PAL),
            PdOrder=await _scoRepository.CountAsync(m=>true)
        };
        return res;
    }
    
    /// <summary>
    /// 采购总数据汇总
    /// </summary>
    /// <returns></returns>
    public async Task<ErpAnalyticalTotalDto> GetCgTotalAsync()
    {
        var res = new ErpAnalyticalTotalDto()
        {
            ProductLoss=await _productRepository.CountAsync(m=>m.ProductTag==ErpProductTagEnum.Scrap),
            PruchaseOrder=await _cgoRepository.CountAsync(m=>true),
            PruchaseMoney= await _cgoRepository.AsQueryable().SumAsync(m=>m.Amount),
            InStock=await _instockRepository.CountAsync(m=>true),
            OutStock= await _outstockRepository.CountAsync(m=>true),
        };
        return res;
    }
    
    /// <summary>
    /// 产品增量统计-月份
    /// </summary>
    /// <returns></returns>
    public async Task<List<ErpProductIncreaseDto>> GetProductIncreaseAsync()
    {
        var res = new List<ErpProductIncreaseDto>();
        var query=await _productRepository.AsQueryable()
            .Where(m => m.CreateTime.Year==year && m.ProductTag==ErpProductTagEnum.Finished)
            .Select(m=>new
            {
                month=m.CreateTime.Month,   
                m.Id
            })
            .MergeTable()
            .GroupBy(m=>new{m.month})
            .Select(m=>new
            {
                Month = m.month,
                Count= SqlFunc.AggregateCount(m.Id)
            })
            .ToListAsync();
        
        var queryMaterial=await _productRepository.AsQueryable()
            .Where(m => m.CreateTime.Year==year && m.ProductTag==ErpProductTagEnum.Materiel)
            .Select(m=>new
            {
                month=m.CreateTime.Month,   
                m.Id
            })
            .MergeTable()
            .GroupBy(m=>new{m.month})
            .Select(m=>new
            {
                Month = m.month,
                Count= SqlFunc.AggregateCount(m.Id)
            })
            .ToListAsync();
        
        for (var i = 1; i < 13; i++)
        {
            var model = query.FirstOrDefault(m=>m.Month==i);
            var modelMaterial = queryMaterial.FirstOrDefault(m=>m.Month==i);
            res.Add(new ErpProductIncreaseDto()
            {
                Month = i>9?i.ToString() : "0"+i,
                ProductCount = model?.Count ?? 0,
                MaterialCount = modelMaterial?.Count ?? 0,
            });
        }
        return res;
    }
    
    /// <summary>
    /// 采购订单趋势
    /// </summary>
    /// <returns></returns>
    public async Task<List<ErpPurchaseIncreaseDto>> GetPurchaseIncreaseAsync()
    {
        var res = new List<ErpPurchaseIncreaseDto>();
        var query=await _cgoRepository.AsQueryable()
            .Where(m => m.CreateTime.Year==year)
            .Select(m=>new
            {
                month=m.CreateTime.Month,   
                money=m.Amount,
                m.Id
            })
            .MergeTable()
            .GroupBy(m=>new{m.month})
            .Select(m=>new
            {
                Month = m.month,
                Money=SqlFunc.AggregateSum(m.money),
                Count= SqlFunc.AggregateCount(m.Id)
            })
            .ToListAsync();
        for (var i = 1; i < 13; i++)
        {
            var model = query.FirstOrDefault(m=>m.Month==i);
            res.Add(new ErpPurchaseIncreaseDto()
            {
                Month = i>9?i.ToString() : "0"+i,
                Count = model?.Count ?? 0,
                Money = model?.Money ?? 0
            });
        }
        return res;
    }

    /// <summary>
    /// 仓库库存占比
    /// </summary>
    /// <returns></returns>
    public async Task<List<ErpWarehouseRatioDto>> GetWarehouseRatioAsync()
    {
        var warehouse = await _warehouseRepository.GetListAsync();
        var wpRepository=_warehouseRepository.ChangeRepository<SugarRepository<ErpWarehouseProduct>>();
        var query = await wpRepository.AsQueryable()
            .Where(m => m.CreateTime.Year==year)
            .GroupBy(m => m.WarehouseId)
            .Select(m => new
            {
                wid=m.WarehouseId,
                count=SqlFunc.AggregateCount(m.WarehouseId)
            }).ToListAsync();
        var res=new List<ErpWarehouseRatioDto>();
        foreach (var item in warehouse)
        {
            var model = query.FirstOrDefault(m => m.wid == item.Id);
            res.Add(new ErpWarehouseRatioDto()
            {
                Name = item.Name,
                Count = model?.count ?? 0,
            });
        }

        return res;
    }
    
    /// <summary>
    /// 年度生产计划完成情况
    /// </summary>
    /// <returns></returns>
    public async Task<List<ErpScIncreaseDto>> GetScIncreaseAsync()
    {
        var query=await _scoRepository.AsQueryable()
            .Where(m => m.CreateTime.Year==year)
            .Select(m=>new
            {
                month=m.CreateTime.Month,
                m.Id
            })
            .MergeTable()
            .GroupBy(m=>new{m.month})
            .Select(m=>new
            {
                Month = m.month,
                Count= SqlFunc.AggregateCount(m.Id)
            })
            .ToListAsync();
        var res=new List<ErpScIncreaseDto>();
        for (var i = 1; i < 13; i++)
        {
            var model = query.FirstOrDefault(m=>m.Month==i);
            res.Add(new ErpScIncreaseDto()
            {
                Month = i>9?i.ToString() : "0"+i,
                Success = model?.Count ?? 0,
            });
        }
        return res;
    }

    /// <summary>
    /// 财务分析
    /// </summary>
    /// <returns></returns>
    public async Task<ErpFinanceTotalDto> GetFinanceTotalAsync()
    {
        var refund=_warehouseRepository.ChangeRepository<SugarRepository<ErpFinanceRefund>>();
        var payment=_warehouseRepository.ChangeRepository<SugarRepository<ErpFinancePayment>>();
        var expense=_warehouseRepository.ChangeRepository<SugarRepository<ErpFinanceReimbursement>>();
        return new ErpFinanceTotalDto()
        {
            Gathering= await refund.AsQueryable().Where(m=>m.CreateTime.Year==year).SumAsync(m=>m.Amount),
            Payment= await payment.AsQueryable().Where(m=>m.CreateTime.Year==year).SumAsync(m=>m.Amount),
            Expense= await expense.AsQueryable().Where(m=>m.CreateTime.Year==year).SumAsync(m=>m.Amount)
        };
    }
}